/*
 * Josh Lindoo
 * Login ID : lind6441
 * CS-102, Winter 2013
 * Programming Assignment 4
 * MovieTree class: Extension of a binary search tree, specifically for movies					
 */

import java.io.*;

public class MovieTree extends BinarySearchTree<Movie> {

	//call parent constructor
	MovieTree() {
		super();
	}
	
	/*
	 * Method: titleLookup
	 * Purpose:	search by title
	 * Parameters:
	 * 		String title: title to search for
	 * 		TreeNode<Movie> currNode:	selected node
	 * Returns: boolean
	 */
	public boolean titleLookup(String title) {
		return titleLookup(title, root);
	}
	private boolean titleLookup(String title, TreeNode<Movie> currNode) {
		
		//if element doesn't exist
		if(currNode == null) return false;
		
		//if matching element found
		if(currNode.getDatum().compareTo(title) == 0) {
			System.out.println("\n" + currNode.getDatum().toString());
			System.out.println("--------------------"); //spacer
			currNode.getDatum().getShowList().printList();
			return true;
		}	
		
		//if current element is < target, continue right, else go left
		if(currNode.getDatum().compareTo(title) < 0)
			return titleLookup(title, currNode.getRight());
		else
			return titleLookup(title, currNode.getLeft());
		
	}
	
	
	/*
	 * Method: idMatcher
	 * Purpose: finds and returns a movie with matching ID
	 * Parameters:
	 * 		int ID: ID to match
	 * 		TreeNode<Movie> currNode:	selected node
	 * Returns: void
	 */
	
	public Movie idMatcher(int ID) {
		return idMatcher(ID, root);
	}
	private Movie idMatcher(int ID, TreeNode<Movie> currNode) {
		
		//if element doesn't exist
		if(currNode == null) return null;
		
		//if matching element found
		if(currNode.getDatum().getID() == ID) {
			return currNode.getDatum();
		}	
		
		Movie leftMovie = idMatcher(ID, currNode.getLeft());
		Movie rightMovie = idMatcher(ID, currNode.getRight());
		
		//If match was found pass it up
		if(leftMovie != null) return leftMovie;
		if(rightMovie != null) return rightMovie;
		
		//Otherwise return null
		return null;
		
	}
	
	
	/*
	 * Method: validate
	 * Purpose: recursive method to validate movies and showings in tree
	 * Parameters:
	 * 		String dateStr: date to validate with
	 * 		TreeNode<Movie> currNode:	selected node
	 * Returns: void
	 */
	
	public void validate(String dateStr) {
		validate(dateStr, root);
	}
	private void validate(String dateStr, TreeNode<Movie> currNode) {
		
		if(currNode == null) return;
		
		//store the current movie obj
		Movie currMovie = currNode.getDatum();
		
		//to the left first
		validate(dateStr, currNode.getLeft());
		
		//validate the showings
		currMovie.getShowList().validate(dateStr);
		
		//remove empty movies
		if(currMovie.getShowList().isEmpty())
			remove(currMovie);
		
		//to the right
		validate(dateStr, currNode.getRight());
		
	}
	
	
	/*
	 * Method: printTree
	 * Purpose: print entire tree of movies and respective showlists
	 * Parameters: none
	 * Returns: void
	 */
	
	public void printTree() {
		
		//print number of movies in DB
		System.out.println(numberOfItems + " Movies in DB..");
		
		//if no movies or showings
		if(numberOfItems == 0)
			System.out.println("No movies or showings in the database..");
		//else print the tree
		else
			printTree(root);
		
	}
	private void printTree(TreeNode<Movie> currNode) {
		
		if(currNode == null) return;
		
		//store current movie obj
		Movie currMovie = currNode.getDatum();
		
		printTree(currNode.getLeft()); //Left
		
		System.out.println("\n" + currMovie); //Root
		System.out.println("--------------------"); //spacer
		currMovie.getShowList().printList();
		
		printTree(currNode.getRight()); //Right
		
	}
	
	/*
	 * Method: writeToDisk
	 * Purpose: write the movie tree and showing lists to disk
	 * Parameters: none
	 * Returns: void
	 */
	
	public void writeToDisk(String moviesName, String showingsName) {
		
		BufferedWriter movieFile;
		BufferedWriter showFile;
		
		//Try to create movie file
		try {
			movieFile = new BufferedWriter(new FileWriter(
														new File(moviesName)));
		}
		catch (IOException exc) {
			System.out.println("\nMovie file already exists..");
			return;
		}
		
		//Try to create showing file
		try {
			showFile = new BufferedWriter(new FileWriter(
													new File(showingsName)));
		}
		catch (IOException exc) {
			System.out.println("\nShowing file already exists..");
			return;
		}
		
		
		writeToDisk(movieFile, showFile, root);
		
		try {
			movieFile.close();
		}
		catch(IOException exc) {
			System.out.println("Write failed..");
		}
		
		try {
			showFile.close();
		}
		catch(IOException exc) {
			System.out.println("Write failed..");
		}
		
	}
	private void writeToDisk(BufferedWriter movieFile, BufferedWriter showFile, 
								TreeNode<Movie> currNode) {
		if(currNode == null) return;
		
		//store current movie obj
		Movie currMovie = currNode.getDatum();
		
		//root
		try {
			movieFile.write(currMovie.export());
			movieFile.newLine();
		}
		catch (IOException exp) {
			System.out.println("Unable to write to movie file..");
			return;
		}
		currMovie.getShowList().writeToDisk(showFile);
		
		//Left
		writeToDisk(movieFile, showFile, currNode.getLeft()); 
		
		
		//Right
		writeToDisk(movieFile, showFile, currNode.getRight()); 
	}

}
